package com.qd.panda.service.billrecord;

import cn.hutool.core.math.Money;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.cdqidi.exception.ApiException;
import com.qd.common.panda.constant.PandaConstant;
import com.qd.common.panda.domain.entity.record.UserBillRecordVO;
import com.qd.common.panda.domain.entity.record.UserBillRecordsDTO;
import com.qd.common.sys.util.SecurityUtils;
import com.qd.panda.model.UserBillRecordsDetails;
import com.qd.panda.model.UserStroke;
import com.qd.panda.service.stroke.BigDecimalUtil;
import com.qd.panda.service.stroke.DisplayUtil;
import com.qd.panda.service.stroke.UserStrokeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Component
@Slf4j
@RequiredArgsConstructor
public class BillRecordsHolderService {
    private final UserBillRecordsService userBillRecordsService;
    private final UserBillRecordsDetailsService billRecordsDetailsService;
    private final UserStrokeService userStrokeService;

    @Transactional(rollbackFor = Exception.class)
    public void saveUserBillRecord(UserBillRecordVO dto) {
        String typeHeader = dto.getTypeHeader();
        userBillRecordsService.checkMb(typeHeader);
        if (typeHeader.equals(PandaConstant.TYPE_HEADER_1)) {
            if (!StringUtils.hasLength(dto.getDutyParagraph())) {
                throw new ApiException("税号不能为空");
            }
        }
        List<String> strokeIds = dto.getStrokeIds();
        userStrokeService.checkIds(strokeIds);
        List<UserBillRecordsDetails> detailsList = billRecordsDetailsService.getBaseMapper().selectBatchIds(strokeIds);
        if (!detailsList.isEmpty()) {
            throw new ApiException("当前行程已经申请，请勿重复申请[" + Arrays.toString(detailsList.stream().map(UserBillRecordsDetails::getSid).toArray()) + "]");
        }
        List<UserStroke> userStrokes = userStrokeService.getBaseMapper().selectBatchIds(strokeIds);
        Money all = new Money();
        for (UserStroke userStroke : userStrokes) {
            if (userStroke.getTripStatus().equals(DisplayUtil.TRIP_STATUS_1)) {
                throw new ApiException("必须要结束的行程才能开票,行程ID[" + userStroke.getSid() + "]");
            }
            all = all.add(new Money(userStroke.getPayAmount()));
        }
        BigDecimal amount = BigDecimalUtil.buildDefaultScale(all.getAmount());
        if (amount.signum() != BigInteger.ONE.signum()) {
            log.error("金额:{}", amount.toPlainString());
            throw new ApiException("无需开票");
        }
        String logId = IdWorker.getIdStr();
        saveRecords(dto, userStrokes.size(), amount, logId);
        saveDetails(strokeIds, logId);

    }

    /**
     * 保存发票申请
     *
     * @param dto    参数
     * @param number 数量
     * @param amount 金额
     * @param logId  日志ID
     */
    private void saveRecords(UserBillRecordVO dto, int number, BigDecimal amount, String logId) {
        UserBillRecordsDTO userBillRecordsDTO = new UserBillRecordsDTO();
        userBillRecordsDTO.setLogId(logId);
        userBillRecordsDTO.setNote(dto.getNote());
        userBillRecordsDTO.setUserId(SecurityUtils.getLoginUser().getUserId());
        userBillRecordsDTO.setAmount(amount);
        userBillRecordsDTO.setUserName(dto.getUserName());
        userBillRecordsDTO.setAddTime(LocalDateTime.now());
        userBillRecordsDTO.setEmail(dto.getEmail());
        userBillRecordsDTO.setDutyParagraph(dto.getDutyParagraph());
        userBillRecordsDTO.setMobile(dto.getMobile());
        userBillRecordsDTO.setMoreMsg(dto.getMoreMsg());
        userBillRecordsDTO.setStrokeNumber(number);
        userBillRecordsDTO.setTitle(dto.getTitle());
        userBillRecordsDTO.setTypeHeader(dto.getTypeHeader());
        userBillRecordsDTO.setStatus(0);
        userBillRecordsService.save(userBillRecordsDTO);
        userBillRecordsDTO.freeData();
    }

    /**
     * 发票对应的行程明细
     *
     * @param strokeIds 行程ID集合
     * @param logId     日志ID
     */
    private void saveDetails(List<String> strokeIds, String logId) {
        List<UserBillRecordsDetails> list = new ArrayList<>();
        strokeIds.forEach(id -> {
            UserBillRecordsDetails userBillRecordsDetails = new UserBillRecordsDetails();
            userBillRecordsDetails.setSid(id);
            userBillRecordsDetails.setLogId(logId);
            list.add(userBillRecordsDetails);
        });
        billRecordsDetailsService.saveBatch(list);
        list.clear();
    }


}
